#ifndef CHANNEL_ENCODER_H_
#define CHANNEL_ENCODER_H_

#include "ff_codec/ff_video_encode.h"
#include "ff_codec/ff_avframe_convert.h"
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <deque>
#include <memory>
#include <utility>
#include <atomic>
#include <iostream>

class ChannelEncoder
{
public:
    ChannelEncoder(std::string url, int dev_id = 0, int que_size = 1) : url_(url), dev_id_(dev_id), max_que_size_(que_size), stop_flag_(true)
    {
        bm_dev_request(&handle_, dev_id_);
        framerate = 25;
        width = 1920;
        height = 1080;
        bitrate = 2000;
        pix_fmt_ = AV_PIX_FMT_NV12;
    }
    ~ChannelEncoder()
    {
        stop();
        thread_->join();
        bm_dev_free(handle_);
    }
    void push_image(std::shared_ptr<bm_image> bmimg);
    int get_image(std::shared_ptr<bm_image> &out_img);

    void start()
    {
        stop_flag_ = false;
        std::cout << "Stream: " + url_ + " output start!" << std::endl;
        thread_ = std::make_shared<std::thread>(&ChannelEncoder::dowork, this);
    }
    void stop()
    {
        stop_flag_ = true;
        std::cout << "Stream: " + url_ + " output  stop!" << std::endl;
    }

private:
    void dowork();

    std::string url_;
    int framerate;
    int width;
    int height;
    int bitrate;
    int dev_id_;
    int max_que_size_;
    bm_handle_t handle_;

    std::deque<std::shared_ptr<bm_image>> img_que_;
    std::mutex img_que_mtx_;
    std::condition_variable que_empty_cv_;

    std::atomic<bool> stop_flag_;
    std::shared_ptr<std::thread> thread_;

    AVPixelFormat pix_fmt_;
    VideoEnc_FFMPEG encoder;
    AVFrame *frame;
};

#endif